<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div th:replace="~{common/common::head}"></div>
<style>
    .slider {
        width: 300px;
        height: 40px;
        background-color: #ddd;
        position: relative;
    }

    .slider-handle {
        width: 40px;
        height: 40px;
        background-color: #4CAF50;
        position: absolute;
        top: 0;
        cursor: pointer;
    }
</style>
<body>
<div class="layuimini-container">
    <div class="layuimini-main">
        <div class="layui-row layui-col-space15">
            <div class="layui-col-md12">
                <fieldset class="layui-elem-field layui-field-title">
                    <legend style="color: rgb(30 159 255)">登录对抗 - JS逆向</legend>
                    <blockquote class="layui-elem-quote layui-quote-nm"
                                style="font-size: 15px;background-color: #a7deefab;box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075) !important">
                        <p>
                        <pre>  JavaScript加密主要用于确保数据在传输和存储过程中的安全性，防止敏感信息被未授权方窃取或篡改……</pre>
                        </p>
                    </blockquote>
                </fieldset>
            </div>

            <div class="layui-col-md12" style="margin-top: 10px">
                <div class="layui-row layui-col-space15">
                    <div class="layui-col-md6">
                        <h1><span class="iconfont icon-bug"> 漏洞场景：sign请求签名绕过</span></h1>
                        <div class="layui-tab layui-tab-brief">
                            <div class="layui-tab-content">
                                <div class="layui-tab-item layui-show">
                                    <blockquote class="layui-elem-quote main_btn">
                                        <form class="layui-form" style="display: flex; justify-content: space-between;">
                                            <div style="display: flex; align-items: center;">
                                                <input type="text" name="username" style="width: 150px;" required
                                                       lay-verify="required" placeholder="用户名" value="admin"
                                                       autocomplete="off"
                                                       class="layui-input">
                                                <input type="text" name="password" style="width: 150px;" required
                                                       lay-verify="required" placeholder="密码" autocomplete="off"
                                                       class="layui-input">
                                            </div>
                                            <div style="display: flex; align-items: center;">
                                                <button class="layui-btn layui-btn-normal"
                                                        style="width: 100px; margin-left: 10px;"
                                                        lay-filter="vul1-reverse-button" lay-submit="">
                                                    <span class="iconfont icon-zhihang">Run</span>
                                                </button>
                                            </div>
                                        </form>
                                    </blockquote>

                                </div>


                                <div class="layui-col-md12">
                                    <div class="layui-card">
                                        <div class="layui-card-header"><i class="fa fa-bullhorn icon-tip"></i>tips</div>
                                        <div class="layui-card-body layui-text layadmin-text">
                                            <pre style="color: #28333e;font-size: 15px;">  增加签名(sign)可以防止请求篡改、重放攻击以及恶意API调用，但是当sign生成复杂度较低时(简单的哈希算法和时间戳),可以通过逆向分析JS代码(例如generateSign函数)，伪造sign参数从而绕过验证</pre>
                                        </div>
                                    </div>
                                </div>

                                <div class="layui-col-md12">
                                    <div class="layui-card">
                                        <div class="layui-card-header"><i class="fa fa-warning icon-output"></i>测试结果
                                        </div>
                                        <div class="layui-card-body layui-text layadmin-text">
                                            <pre id="vul1-reverse-result"
                                                 style="color: red;font-size: 15px;"></pre>
                                        </div>
                                    </div>
                                </div>

                            </div>
                        </div>
                    </div>

                    <div class="layui-col-md6">
                        <h1><span class="iconfont icon-code"> 缺陷代码</span></h1>
                        <div class="m-auto div-shadow shadow p-3 mb-5 bg-white rounded">
                            <div class="code-editor" id="vul1Reverse"></div>
                        </div>
                    </div>

                </div>
            </div>

            <div class="layui-col-md12" style="margin-top: 10px">
                <div class="layui-row layui-col-space15">
                    <div class="layui-col-md6">
                        <h1><span class="iconfont icon-bug"> 漏洞场景：RSA前端加密绕过</span></h1>
                        <div class="layui-tab layui-tab-brief">
                            <div class="layui-tab-content">
                                <div class="layui-tab-item layui-show">
                                    <blockquote class="layui-elem-quote main_btn">
                                        <form class="layui-form" style="display: flex; justify-content: space-between;">
                                            <div style="display: flex; align-items: center;">
                                                <input type="text" name="username" style="width: 150px;" required
                                                       lay-verify="required" placeholder="用户名" value="admin"
                                                       autocomplete="off"
                                                       class="layui-input">
                                                <input type="text" name="password" style="width: 150px;" required
                                                       lay-verify="required" placeholder="密码" autocomplete="off"
                                                       class="layui-input">
                                            </div>
                                            <div style="display: flex; align-items: center;">
                                                <button class="layui-btn layui-btn-normal"
                                                        style="width: 100px; margin-left: 10px;"
                                                        lay-filter="vul2-reverse-button" lay-submit="">
                                                    <span class="iconfont icon-zhihang">Run</span>
                                                </button>
                                            </div>
                                        </form>
                                    </blockquote>

                                </div>


                                <div class="layui-col-md12">
                                    <div class="layui-card">
                                        <div class="layui-card-header"><i class="fa fa-bullhorn icon-tip"></i>tips</div>
                                        <div class="layui-card-body layui-text layadmin-text">
                                            <pre style="color: #28333e;font-size: 15px;">  攻击者可以通过获取公钥伪造数据，绕过后端的逻辑处理……</pre>
                                        </div>
                                    </div>
                                </div>

                                <div class="layui-col-md12">
                                    <div class="layui-card">
                                        <div class="layui-card-header"><i class="fa fa-warning icon-output"></i>测试结果
                                        </div>
                                        <div class="layui-card-body layui-text layadmin-text">
                                            <pre id="vul2-reverse-result"
                                                 style="color: red;font-size: 15px;"></pre>
                                        </div>
                                    </div>
                                </div>

                            </div>
                        </div>
                    </div>

                    <div class="layui-col-md6">
                        <h1><span class="iconfont icon-code"> 缺陷代码</span></h1>
                        <div class="m-auto div-shadow shadow p-3 mb-5 bg-white rounded">
                            <div class="code-editor" id="vul2Reverse"></div>
                        </div>
                    </div>

                </div>
            </div>


        </div>
    </div>
</div>
</div>

<div th:replace="~{common/common::script}"></div>
<script src="https://cdn.jsdelivr.net/npm/js-md5@0.7.3/build/md5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jsencrypt@3.0.0-rc.2/bin/jsencrypt.min.js"></script>
<script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function () {

        layui.use(['layer', 'miniTab', 'common', 'form'], function () {
            var $ = layui.jquery,
                layer = layui.layer,
                miniTab = layui.miniTab,
                common = layui.common,
                form = layui.form;
            miniTab.listen();
            layer.msg("登录对抗 - JS逆向")

            // 请求签名绕过
            form.on('submit(vul1-reverse-button)', function (data) {
                const key = "FF38DC304A1D74B19F24A36C09FD6B72";

                function generateSign(params) {
                    const query = Object.keys(params)
                        .sort()
                        .map(k => `${k}=${params[k]}`)
                        .join("&");
                    return md5(query + key); // 使用 MD5 加密生成签名
                }

                const params = {
                    username: data.field.username,
                    password: data.field.password,
                    timestamp: Date.now(),
                };

                const sign = generateSign(params);

                $.ajax({
                    url: '/loginconfront/reverse/vul1',
                    type: 'POST',
                    contentType: 'application/json',
                    data: JSON.stringify({
                        ...params,
                        sign: sign,
                    }),
                    success: function (res) {
                        if (res.code === 0) {
                            $("#vul1-reverse-result").text(res.msg);
                        } else {
                            $("#vul1-reverse-result").text(res.msg);
                        }
                    },
                    error: function (err) {
                        console.error("请求失败：", err);
                        $("#vul1-reverse-result").text("请求失败，请稍后重试！");
                    }
                });

                return false;
            });

            // 代码混淆
            form.on('submit(vul2-reverse-button)', function (data) {
                const publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx6Iq6tBvjNHqczQmJJAo
otsBfKM/9yJCuTV87ZlI0Y1EFG65Jo89aLHW7BqBUJepcKC9kcA5PJaWSF5BYElt
Y2NPnIfGkHamKeFywWh4aYy66MlBqr91Fw0Wyx8PQlp0CJKfiPEQmzwUobpimAvK
BdI1k00veCNbf+h83JtfrZFJDwc0E0DMZq+Bg3dRmQdXXR927j3wXP9sE5s0hv9G
qND8uGY/TKPRu27rrVJVEFTztPBQM8Qnka29yI27+C6O9OpqeFLlxg89ripgokon
ynya/GuxO7kRkSnl7hvjjdkQEOLVGJmO7KgzOFnzlCMUemkbakGp/OMmhq9GyNqS
oQIDAQAB
-----END PUBLIC KEY-----
`;

                const encryptField = (field) => {
                    const encryptor = new JSEncrypt();
                    encryptor.setPublicKey(publicKey); // 设置公钥
                    return encryptor.encrypt(field); // 返回加密后的 Base64 字符串
                };

                const encryptedUsername = encryptField(data.field.username);
                const encryptedPassword = encryptField(data.field.password);

                $.ajax({
                    url: '/loginconfront/reverse/vul2',
                    type: 'POST',
                    contentType: 'application/json',
                    data: JSON.stringify({
                        encryptedUsername,
                        encryptedPassword,
                    }),
                    success: function (res) {
                        if (res.code === 0) {
                            $("#vul2-reverse-result").text(res.msg);
                        } else {
                            $("#vul2-reverse-result").text(res.msg);
                        }
                    },
                    error: function (err) {
                        console.error("请求失败：", err);
                        $("#vul2-reverse-result").text("请求失败，请稍后重试！");
                    }
                });

                return false; // 阻止表单默认提交
            });


            var cmConfig = {
                lineNumbers: true,
                lineWrapping: false,
                indentUnit: 4,
                indentWithTabs: true,
                theme: 'juejin',
                styleActiveLine: {nonEmpty: true},
                fontSize: "18px",
                mode: "text/x-java"
            };

            CodeMirror(document.getElementById("vul1Reverse"), Object.assign({}, cmConfig, {
                value: vul1Reverse
            }));
            CodeMirror(document.getElementById("vul2Reverse"), Object.assign({}, cmConfig, {
                value: vul2Reverse
            }));

        });
    });


</script>

</body>
</html>
